package com.qf.service;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.qf.Cinema;
import com.qf.ResultVo;
import com.qf.dto.SearchDTO;
import com.qf.mapper.CinemaSearchMapper;
import com.qf.service.CinemaSearchService;
import com.qf.vo.PageResultVo;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 作者：Xx凯丶
 * 时间：2022/4/19 15:16
 */
@Service
public class CinemaSearchServiceImpl implements CinemaSearchService {
    @Autowired
    private ElasticsearchRestTemplate template;
    @Autowired
    private CinemaSearchMapper cinemaSearchMapper;
    @Override
    public Map<String, List<String>> findBucket() {
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        TermsAggregationBuilder typeAggregationBuilder = AggregationBuilders.terms("hType").field("hallType").size(100);
        TermsAggregationBuilder bNameAggregationBuilder = AggregationBuilders.terms("bName").field("brandName").size(100);
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(matchAllQueryBuilder)
                .addAggregation(typeAggregationBuilder)
                .addAggregation(bNameAggregationBuilder)
                .build();
        SearchHits<Cinema> searchRes = template.search(query, Cinema.class);
        List<SearchHit<Cinema>> searchHits = searchRes.getSearchHits();
        Aggregations aggregations = searchRes.getAggregations();
        Terms hType = aggregations.get("hType");

        List<String> hTypes = hType.getBuckets().stream().map(item -> (String) item.getKey()).collect(Collectors.toList());
        Terms bName = aggregations.get("bName");
        List<String> bNames = bName.getBuckets().stream().map(item -> (String) item.getKey()).collect(Collectors.toList());

        return new HashMap(){{
            put("hTypes",hTypes);
            put("bNames",bNames);
        }};
    }

    @Override
    public PageResultVo<Cinema> search(SearchDTO searchDTO) {
        if (searchDTO == null) {
            return  new PageResultVo<>(false,"非法参数");
        }
        String keyword = searchDTO.getKeyword();
        String typeFilter = searchDTO.getTypeFilter();
        String bNameFilter = searchDTO.getBrandNameFilter();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(!StringUtils.isEmpty(keyword)){
            MatchQueryBuilder movieCh = QueryBuilders.matchQuery("cinemaName", keyword);
            boolQueryBuilder.must(movieCh);



        }
        if(!StringUtils.isEmpty(typeFilter)){
            MatchQueryBuilder types = QueryBuilders.matchQuery("hallType",  typeFilter);
            boolQueryBuilder.must(types);
        }
        if(!StringUtils.isEmpty(bNameFilter)){
            MatchQueryBuilder brandName
                    = QueryBuilders.matchQuery("brandName", bNameFilter);
            boolQueryBuilder.must(brandName);
        }
        PageRequest pageRequest = PageRequest.of((searchDTO.getPage() - 1) < 0 ? 0 : (searchDTO.getPage() - 1), searchDTO.getSize());
        TermsAggregationBuilder typeAggregationBuilder = AggregationBuilders.terms("hType").field("hallType").size(100);
        TermsAggregationBuilder bNameAggregationBuilder = AggregationBuilders.terms("bName").field("brandName").size(100);

        if(!StringUtils.isEmpty(typeFilter)){
            TermQueryBuilder hType = QueryBuilders.termQuery("hallType", typeFilter);
            boolQueryBuilder.filter(hType);
        }

        if(!StringUtils.isEmpty(bNameFilter)){
            TermQueryBuilder bName = QueryBuilders.termQuery("brandName", bNameFilter);
            boolQueryBuilder.filter(bName);
        }

        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder()
                //指定查询方式
                .withQuery(boolQueryBuilder)
                .withPageable(pageRequest)
                .addAggregation(typeAggregationBuilder)
                .addAggregation(bNameAggregationBuilder);
        SearchHits<Cinema> searchRes = template.search(nativeSearchQueryBuilder.build(), Cinema.class);
        //获取总记录数
        long totalHits = searchRes.getTotalHits();
        List<Cinema> cinemas = searchRes.stream().map(hit -> hit.getContent()).collect(Collectors.toList());
        Aggregations aggregations = searchRes.getAggregations();
        Terms hType = aggregations.get("hType");

        List<String> hTypes = hType.getBuckets().stream().map(item -> (String) item.getKey()).collect(Collectors.toList());
        Terms place = aggregations.get("bName");
        List<String> bNames = place.getBuckets().stream().map(item -> (String) item.getKey()).collect(Collectors.toList());
        PageResultVo<Cinema> pageResultVo = new PageResultVo<>(true, "success");
        pageResultVo.setTotal(totalHits);
        pageResultVo.setData(cinemas);
        pageResultVo.setHTypes(hTypes);
        pageResultVo.setBNames(bNames);
        return pageResultVo;
    }


}
